#pragma once

#include "CDependencyObject.h"


class CTransform;
class CMILMatrix;
class CFrameVectorBuffer;
class CPlainPen;
class CBrush;
class CRasterizerPath;
class CRasterizerEdgeStore;
class CRenderTarget;
class HitTestPolygon;
class CLayer;
class CWideningSink;


class CGeometry :
	public CDependencyObject
{

private: void Initialize();

protected: 
	CGeometry();
	CGeometry(CCoreServices *);
	virtual ~CGeometry();
public: 
	static HRESULT Create(CDependencyObject * * ppObject, CREATEPARAMETERS * pCreate);
	virtual XUINT32 GetTypeIndex() const;
	HRESULT CheckNewTransform(const CMILMatrix * pCurrentTransform, const CFrameVectorBuffer * pFrameVectorBuffer, const CMILMatrix * pStretch, CBrush * pStroke, CBrush * pFill, XBOOL * pfIsInsideFrame);
	void InvalidateFillEdgeStore();
	void InvalidateEdgeStores();
	XBOOL HasEdgeStore();
	XBOOL HasEdges();
	XBOOL IsRectangular();
	virtual HRESULT AddToPath(const CMILMatrix *) = 0;
	HRESULT AddToRenderList(XFLOAT rOpacity, CBrush * pFillBrush, XBOOL fFillBrushChanged, CPlainPen * pPen, CBrush * pStrokeBrush, XBOOL fStrokeBrushChanged, struct IBrushSpan * pIBrushSpanLayer, xvector<xref_ptr<CRasterizerEdgeStore> > & vecEdgeStores, const CFrameVectorBuffer * pFrameVectorBuffer, CLayer * pTargetLayer, struct XRECTF_WH * pRenderBounds, enum XcpBrushStretch stretch, XBOOL fCheckTransform, const CMILMatrix * pRenderTransform, XBOOL fApplyRenderClip, XBOOL fForceAddEdges, XBOOL * pfIsInsideFrame);
	virtual HRESULT RegeneratePathData();
	virtual HRESULT GetBounds(struct XRECTF_RB * pBounds);
	static HRESULT GetBounds(struct Xcp_IDependencyObject * pObject, XUINT32 cArgs, CValue * pArgs, CValue * pResult);
	HRESULT ComputeStretchMatrix(enum XcpBrushStretch stretch, const struct XRECTF_WH * pRenderBounds, const struct XRECTF_WH * pNaturalBounds, CMILMatrix * pTransform);
	virtual XBOOL CanBeAccelerated();
	virtual HRESULT CloneForTarget(CRenderTarget * pRenderTarget, CGeometry * * ppGeometry);
	HRESULT GetGeometryNaturalBounds(struct XRECTF_RB *);
protected: 
	HRESULT CopyGeometryProperties(CRenderTarget * pRenderTarget, CGeometry * pGeometry);
	void Invalidate();
private: 
	HRESULT EnsureFillPath();
	void InvalidateStrokeEdgeStore();
	HRESULT AddToFrameBuffer(const CMILMatrix * pRenderTransform, enum XcpShapeMaskMode shapeMaskMode, XFLOAT rOpacity, CRasterizerPath * pRasterizerPath, CPlainPen * pPen, CBrush * pBrush, XBOOL fBrushChanged, struct IBrushSpan * pIBrushSpanLayer, xvector<xref_ptr<CRasterizerEdgeStore> > & vecEdgeStores, const CFrameVectorBuffer * pFrameVectorBuffer, CLayer * pLayer, const struct XRECTF_WH * pRenderBounds, const struct XRECTF_WH * prcUnstretchedBounds, const CMILMatrix * pmatStretch, XBOOL fStoreTransformed, XBOOL fApplyRenderClip, XBOOL fForceAddEdges);
public: 
	virtual HRESULT GetWidenedBounds(const CPlainPen & pen, struct XRECTF_RB * pBounds);
	HRESULT FillContainsPoint(const struct XPOINTF &, const CMILMatrix *, XUINT32 *);
	virtual HRESULT HitTestFill(const HitTestPolygon & target, const CMILMatrix * pTransform, XBOOL * pHit);
	virtual HRESULT HitTestFill(const struct XPOINTF & target, const CMILMatrix * pTransform, XBOOL * pHit);
	virtual HRESULT ClipToFill(HitTestPolygon & target, const CMILMatrix * pTransform, XBOOL * pHit);
	virtual HRESULT ClipToFill(struct XPOINTF & target, const CMILMatrix * pTransform, XBOOL * pHit);
	HRESULT StrokeContainsPoint(const struct XPOINTF &, const CPlainPen &, const CMILMatrix *, XBOOL *);
	virtual HRESULT HitTestStroke(const HitTestPolygon & target, const CPlainPen & pen, const CMILMatrix * pTransform, XBOOL * pHit);
	virtual HRESULT HitTestStroke(const struct XPOINTF & target, const CPlainPen & pen, const CMILMatrix * pTransform, XBOOL * pHit);
	virtual HRESULT VisitSink(struct IPALGeometrySink * pSink);
protected: 
	virtual HRESULT VisitSinkInternal(struct IPALGeometrySink *) = 0;
	HRESULT WidenToSink(const CPlainPen & pen, const CMILMatrix * pTransform, CWideningSink * pSink);
public: 
	CTransform * m_pTransform ;
	CRasterizerPath * m_pFillPath;
	CRasterizerPath * m_pStrokePath;
	enum XcpFillMode m_fillMode;

	XBOOL m_fSmoothJoin:1;
	XBOOL m_fNeedsStretching:1;
private: 
	XBOOL m_fNWHasLayerEdgeStore:1;

public: 
	HRESULT NWSetUpClip(struct SharedRenderParams & sharedRP, struct NWRenderParams & nwRP, XBOOL fClipContentsDirty);
	HRESULT NWAddClipToFrameBuffer(CFrameVectorBuffer * pFrameVectorBuffer, XBOOL fIsLayerSharedBetweenVectorBuffers, XBOOL fIsLastAddCallForFrame, XBOOL fUpdateLayerWithoutAdding);
private: 
	HRESULT EnsureEdgeStoreForRasterizerPath(const CMILMatrix * pRenderTransform, CRasterizerPath * pRasterizerPath, CPlainPen * pPen, const CMILMatrix * pStretchMatrix);
	HRESULT ApplyBrushClipsToEdgeStore(const CMILMatrix *, CRasterizerEdgeStore *, CBrush *, enum XcpBrushStretch, struct XRECTF_WH *);
	HRESULT NWSetEdgeStoreBrush(CRasterizerEdgeStore *, CBrush *, const CMILMatrix *, enum XcpBrushStretch, struct XRECTF_WH *);
	void GetStrokeAdjustedElementBounds(struct XRECTF_WH * pElementBounds, const struct XRECTF_WH & naturalBounds, XFLOAT penThickness, struct XRECTF_WH * pStrokeAdjustedElementBounds);
public: 
	struct IPALAcceleratedGeometry * GetAcceleratedGeometry();
	void ReleaseAcceleratedGeometry();
	HRESULT GetAcceleratedGeometryBounds(XFLOAT rStrokeThickness, struct XRECTF_RB * pBounds);
	HRESULT GetAcceleratedGeometryBounds(XFLOAT rStrokeThickness, struct XRECTF_WH * pBounds);

	static HRESULT DrawAccelerated(struct IPALAcceleratedGeometry * pPALAcceleratedGeometry, const struct D2DRenderParams & d2dRP, const CMILMatrix * pWorldTransform, XFLOAT strokeThickness, struct IPALStrokeStyle * pStrokeStyle, XFLOAT opacity, struct IPALAcceleratedBrush * pPALBrush, struct AcceleratedBrushParams * pPALBrushParams);
	
	HRESULT DrawAccelerated(const struct D2DRenderParams & d2dRP, const CMILMatrix * pWorldTransform, XFLOAT strokeThickness, struct IPALStrokeStyle * pStrokeStyle, XFLOAT opacity, struct IPALAcceleratedBrush * pPALBrush, struct AcceleratedBrushParams * pPALBrushParams);
	
	HRESULT UpdateAcceleratedGeometry(const struct D2DPrecomputeParams & cp, struct IPALAcceleratedGraphicsFactory * pD2DFactory, struct XRECTF_WH * pElementBounds, enum XcpBrushStretch stretch, XFLOAT rPenThickness);
	HRESULT UpdateAcceleratedGeometry(const struct D2DPrecomputeParams & cp);
protected: 
	virtual HRESULT UpdateAcceleratedGeometryVirtual(const struct D2DPrecomputeParams & cp);
	HRESULT SetUntransformedAcceleratedGeometry(struct IPALAcceleratedGraphicsFactory * pD2DFactory, struct IPALAcceleratedGeometry * pPALGeometry);
public: 
	HRESULT GetPrintGeometry(const struct D2DPrecomputeParams & cp, const struct D2DRenderParams & printParams, struct XRECTF_WH * pElementBounds, enum XcpBrushStretch stretch, XFLOAT rPenThickness, struct IPALAcceleratedGeometry * * ppGeometry);
	HRESULT GetPrintGeometry(const struct D2DPrecomputeParams & cp, const struct D2DRenderParams & printParams, struct IPALAcceleratedGeometry * * ppGeometry);
protected: 
	virtual HRESULT GetPrintGeometryVirtual(const struct D2DPrecomputeParams & cp, const struct D2DRenderParams & printParams, struct IPALAcceleratedGeometry * * ppGeometry);
	struct XRECTF_RB m_palGeometryBounds;
private: 
	struct IPALAcceleratedGeometry * m_pPALAcceleratedGeometry;



};